package com.wxm.china.port.dds.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wxm.china.port.dds.exception.DDSException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

/**
 * <p>
 *      OkHttp工具类
 * </p>
 *
 * @author: wxm
 * @Date: 2023/6/30
 */
@Slf4j
public class OkHttpUtils {
    private OkHttpUtils(){}
    private static final OkHttpClient client = new OkHttpClient()
            .newBuilder()
            .connectTimeout(10, TimeUnit.SECONDS) // 设置超时时间
            .readTimeout(10, TimeUnit.SECONDS) // 设置读取超时时间
            .writeTimeout(10, TimeUnit.SECONDS) // 设置写入超时时间
            .build();

    /**
     * 发送GetParam请求
     * @param url URL
     * @param param 参数
     * @param aClass aClass
     * @param processor processor
     * @param <T> T
     * @param <E> E
     * @return E
     */
    public static <T,E> E sendGetParam(String url, JSONObject param, Class<T> aClass, BiFunction<String,Class<T>,E> processor){
        String result = "";
        String nowUrl = url + (param.keySet().size() > 0 ? "?" + param.keySet().stream().map(item -> item + "=" + param.getString(item)).collect(Collectors.joining("&"))  : "");
        log.info("{} Get请求已经准备就绪： URL：{} 参数：{}",ConstantUtils.LOG_PREFIX,url,param);
        Request request = new Request.Builder().url(nowUrl).build();

        try (Response response = client.newCall(request).execute()) {
            result = response.body().string();
            log.info("{} 请求结果 {}",ConstantUtils.LOG_PREFIX,result);
        } catch (IOException e) {
            DDSException.error("GET请求失败" + e.getMessage());
        }
        E e = processor.apply(result,aClass);
        log.info("{} 返回处理结果：{}",ConstantUtils.LOG_PREFIX, e);
        return e;
    }

    /**
     * 发送PostJson请求
     * @param url URL
     * @param param 参数
     * @param aClass aClass
     * @param processor processor
     * @param <T> T
     * @param <E> E
     * @return E
     */
    public static <T,E> E sendPostJson(String url,JSONObject param,Class<T> aClass,BiFunction<String,Class<T>,E> processor){
        String result = "";
        RequestBody body = RequestBody.create(param.toJSONString(), MediaType.get("application/json;charset=UTF-8"));
        log.info("{} Post-Json 请求已经准备就绪： URL：{} 参数：{}",ConstantUtils.LOG_PREFIX,url,param);
        Request request = new Request.Builder().url(url).post(body).build();
        try (Response response = client.newCall(request).execute()) {
            result = response.body().string();
            log.info("{} 请求结果 {}",ConstantUtils.LOG_PREFIX,result);
        } catch (IOException e) {
            DDSException.error("POST-Json请求失败" + e.getMessage());
        }
        E e = processor.apply(result,aClass);
        log.info("{} 返回处理结果：{}",ConstantUtils.LOG_PREFIX, e);
        return e;
    }

    public static <T,E> E sendPostFormData(String url,JSONObject param,Class<T> aClass,BiFunction<String,Class<T>,E> processor){
        String result = "";
        log.info("{} Post-FormData 请求已经准备就绪： URL：{} 参数：{}",ConstantUtils.LOG_PREFIX,url,param);
        MultipartBody.Builder builder = new MultipartBody.Builder();
        for (String key : param.keySet()) {
            builder.addFormDataPart(key,param.getString(key));
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        try (Response response = client.newCall(request).execute()) {
            result = response.body().string();
            log.info("{} 请求结果 {}",ConstantUtils.LOG_PREFIX,result);
        } catch (IOException e) {
            DDSException.error("POST-FormData请求失败" + e.getMessage());
        }
        E e = processor.apply(result,aClass);
        log.info("{} 返回处理结果：{}",ConstantUtils.LOG_PREFIX, e);
        return e;
    }

    /**
     * res返回数据处理器(将data解析出)
     * @param result result
     * @return String
     */
    private static String resProcessor(String result){
        DdsR<?> r = JSONObject.parseObject(result,DdsR.class);
        //判断响应是否正常
        if (!r.getCode().equals(200)){
            DDSException.error("数据请求失败：" + r.getMsg());
        }
        //获取返回的data
        return JSONObject.toJSONString(r.getData());
    }

    /**
     * 数据返回<R>
      * @param result result
     * @param rClass rClass
     * @param <R> R
     * @return R
     */
    public static <R> R resultObjectR(String result, Class<R> rClass){
        String str = OkHttpUtils.resProcessor(result);
        return JSONObject.parseObject(str).toJavaObject(rClass);
    }

    /**
     * 数据返回List<R>
     * @param result result
     * @param rClass rClass
     * @param <R> R
     * @return List<R>
     */
    public static <R> List<R> resultArrayR(String result, Class<R> rClass){
        String str = OkHttpUtils.resProcessor(result);
        return JSONArray.parseArray(str).toJavaList(rClass);
    }
}
